package gui;

import java.util.Iterator;
import java.util.List;

import main.Building;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

public class Window {
	private boolean done = false;
	private boolean fullscreen = false;
	private boolean f1 = false;

	private float rquady = 0f;
	private float rquadx = 0f;
	private int s_x;
	private int s_y;
	private DisplayMode displayMode;
	private List<Building> buildings;
	
	public Window(List<Building> buildings) {
		this.buildings = buildings;
		int minx = Integer.MAX_VALUE;
		int maxx = Integer.MIN_VALUE;
		int miny = Integer.MAX_VALUE;
		int maxy = Integer.MIN_VALUE;
		Iterator<Building> it = buildings.iterator();
		while(it.hasNext()) {
			Building b = it.next();
			if(b.getXPos() < minx) {
				minx = b.getXPos();
			}
			if(b.getXPos()+ b.x > maxx) {
				maxx = b.getXPos() + b.x;
			}
			if(b.getYPos() < miny) {
				miny = b.getYPos();
			}
			if(b.getYPos() + b.y > maxy) {
				maxy = b.getYPos() + b.y;
			}
		}
		it = buildings.iterator();
		if(minx<0 || miny<0) {
			while(it.hasNext()) {
				Building b = it.next();
				if(minx<0) {
					b.setxPos(b.getXPos() - minx);
				}
				if(miny<0) {
					b.setyPos(b.getYPos() - miny);
				}
			}
		}
		
		s_x = maxx-minx;
		s_y = maxy-miny;
	}

	/*public static void main(String args[]) {
		boolean fullscreen = false;
		if (args.length > 0) {
			if (args[0].equalsIgnoreCase("fullscreen")) {
				fullscreen = true;
			}
		}

		Window l5 = new Window();
		l5.run(fullscreen);
	}*/

	public void run(boolean fullscreen) {
		this.fullscreen = fullscreen;
		try {
			init();
			while (!done) {
				mainloop();
				render();
				Display.update();
			}
			cleanup();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(0);
		}
	}

	private void mainloop() {
		if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { // Exit if Escape is
														// pressed
			done = true;
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) { // Exit if Escape is
			// pressed
			this.rquady -= 0.03;
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) { // Exit if Escape is
			// pressed
			this.rquady += 0.03;
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_UP)) { // Exit if Escape is
			// pressed
			this.rquadx -= 0.03;
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) { // Exit if Escape is
			// pressed
			this.rquadx += 0.03;
		}
		
		if (Display.isCloseRequested()) { // Exit if window is closed
			done = true;
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_F1) && !f1) { // Is F1 Being
															// Pressed?
			f1 = true; // Tell Program F1 Is Being Held
			switchMode(); // Toggle Fullscreen / Windowed Mode
		}
		if (!Keyboard.isKeyDown(Keyboard.KEY_F1)) { // Is F1 Being Pressed?
			f1 = false;
		}
	}

	private void switchMode() {
		fullscreen = !fullscreen;
		try {
			Display.setFullscreen(fullscreen);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void drawCube() {
		
		
		
		GL11.glColor3f(0.5f, 0.5f, 1.0f); // Set The Color To Blue One Time Only
		
		GL11.glBegin(GL11.GL_QUADS); // Draw A Quad
		//GL11.glDepthRange(0.f, 0.f);
		
		GL11.glColor3f(0.0f, 1.0f, 0.0f); // Set The Color To Green
		GL11.glVertex3f(1.0f, 1.0f, 0.0f); // Top Right Of The Quad (Top)
		GL11.glVertex3f(0.0f, 1.0f, 0.0f); // Top Left Of The Quad (Top)
		GL11.glVertex3f(0.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
		GL11.glVertex3f(1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
		GL11.glColor3f(1.0f, 0.5f, 0.0f); // Set The Color To Orange
		GL11.glVertex3f(1.0f, 0.0f, 1.0f); // Top Right Of The Quad (Bottom)
		GL11.glVertex3f(0.0f, 0.0f, 1.0f); // Top Left Of The Quad (Bottom)
		GL11.glVertex3f(0.0f, 0.0f, 0.0f); // Bottom Left Of The Quad
												// (Bottom)
		GL11.glVertex3f(1.0f, 0.0f, 0.0f); // Bottom Right Of The Quad
												// (Bottom)
		GL11.glColor3f(1.0f, 0.0f, 0.0f); // Set The Color To Red
		GL11.glVertex3f(1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
		GL11.glVertex3f(0.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
		GL11.glVertex3f(0.0f, 0.0f, 1.0f); // Bottom Left Of The Quad (Front)
		GL11.glVertex3f(1.0f, 0.0f, 1.0f); // Bottom Right Of The Quad (Front)
		GL11.glColor3f(1.0f, 1.0f, 0.0f); // Set The Color To Yellow
		GL11.glVertex3f(1.0f, 0.0f, 0.0f); // Bottom Left Of The Quad (Back)
		GL11.glVertex3f(0.0f, 0.0f, 0.0f); // Bottom Right Of The Quad (Back)
		GL11.glVertex3f(0.0f, 1.0f, 0.0f); // Top Right Of The Quad (Back)
		GL11.glVertex3f(1.0f, 1.0f, 0.0f); // Top Left Of The Quad (Back)
		GL11.glColor3f(0.0f, 0.0f, 1.0f); // Set The Color To Blue
		GL11.glVertex3f(0.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
		GL11.glVertex3f(0.0f, 1.0f, 0.0f); // Top Left Of The Quad (Left)
		GL11.glVertex3f(0.0f, 0.0f, 0.0f); // Bottom Left Of The Quad (Left)
		GL11.glVertex3f(0.0f, 0.0f, 1.0f); // Bottom Right Of The Quad (Left)
		GL11.glColor3f(1.0f, 0.0f, 1.0f); // Set The Color To Violet
		GL11.glVertex3f(1.0f, 1.0f, 0.0f); // Top Right Of The Quad (Right)
		GL11.glVertex3f(1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
		GL11.glVertex3f(1.0f, 0.0f, 1.0f); // Bottom Left Of The Quad (Right)
		GL11.glVertex3f(1.0f, 0.0f, 0.0f); // Bottom Right Of The Quad (Right)
		 
		GL11.glEnd(); // Done Drawing The Quad
		
		//GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
		GL11.glBegin(GL11.GL_LINES);
		//GL11.glDepthRange(1.f, 1.f);
		GL11.glColor3f(0.0f, 0.0f, 0.0f);
		GL11.glVertex3f(1.0f, 1.0f, 0.0f); // Top Right Of The Quad (Top)
		GL11.glVertex3f(0.0f, 1.0f, 0.0f); // Top Left Of The Quad (Top)
		GL11.glVertex3f(0.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
		GL11.glVertex3f(1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
		GL11.glVertex3f(1.0f, 0.0f, 1.0f); // Top Right Of The Quad (Bottom)
		GL11.glVertex3f(0.0f, 0.0f, 1.0f); // Top Left Of The Quad (Bottom)
		GL11.glVertex3f(0.0f, 0.0f, 0.0f); // Bottom Left Of The Quad
												// (Bottom)
		GL11.glVertex3f(1.0f, 0.0f, 0.0f); // Bottom Right Of The Quad
												// (Bottom)
		GL11.glVertex3f(1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
		GL11.glVertex3f(0.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
		GL11.glVertex3f(0.0f, 0.0f, 1.0f); // Bottom Left Of The Quad (Front)
		GL11.glVertex3f(1.0f, 0.0f, 1.0f); // Bottom Right Of The Quad (Front)
		GL11.glVertex3f(1.0f, 0.0f, 0.0f); // Bottom Left Of The Quad (Back)
		GL11.glVertex3f(0.0f, 0.0f, 0.0f); // Bottom Right Of The Quad (Back)
		GL11.glVertex3f(0.0f, 1.0f, 0.0f); // Top Right Of The Quad (Back)
		GL11.glVertex3f(1.0f, 1.0f, 0.0f); // Top Left Of The Quad (Back)
		GL11.glVertex3f(0.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
		GL11.glVertex3f(0.0f, 1.0f, 0.0f); // Top Left Of The Quad (Left)
		GL11.glVertex3f(0.0f, 0.0f, 0.0f); // Bottom Left Of The Quad (Left)
		GL11.glVertex3f(0.0f, 0.0f, 1.0f); // Bottom Right Of The Quad (Left)
		GL11.glVertex3f(1.0f, 1.0f, 0.0f); // Top Right Of The Quad (Right)
		GL11.glVertex3f(1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
		GL11.glVertex3f(1.0f, 0.0f, 1.0f); // Bottom Left Of The Quad (Right)
		GL11.glVertex3f(1.0f, 0.0f, 0.0f);
		GL11.glEnd();
	}

	private boolean render() {
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); 

		float draw_size = 10.f;
		float draw_oszto = draw_size/Math.max(s_x, s_y);
		
		Iterator<Building> it = buildings.iterator();

		 // Reset The Current Modelview Matrix
		GL11.glLoadIdentity();
	
		GL11.glTranslatef(0f, 0.f, -20.0f);
		GL11.glRotatef(rquady, 0.0f, 1.0f, .0f);
		GL11.glRotatef(rquadx, 1.0f, 0.0f, 0.0f);
		while(it.hasNext()) {
			Building b = it.next();
			
			GL11.glPushMatrix();
			
			GL11.glTranslatef(-draw_size/2.f+b.getXPos()*draw_oszto, 0.f, -draw_size/2.f+b.getYPos()*draw_oszto);
			
			GL11.glScalef(b.x*draw_oszto, b.h*draw_oszto, b.y*draw_oszto);
			
			drawCube();
			GL11.glPopMatrix();
		}
		
		GL11.glBegin(GL11.GL_QUADS);
		GL11.glColor3f(0.5f, 0.5f, 0.5f); 
		GL11.glVertex3f(-draw_size/2f, 0.0f, -draw_size/2f); // Top Right Of The Quad (Top)
		GL11.glVertex3f(-draw_size/2f, 0.0f, draw_size/2f); // Top Left Of The Quad (Top)
		GL11.glVertex3f(draw_size/2f, 0.0f, draw_size/2f); // Bottom Left Of The Quad (Top)
		GL11.glVertex3f(draw_size/2f, 0.0f, -draw_size/2f); // Bottom Right Of The Quad (Top)
		GL11.glEnd();
		
		return true;
	}

	private void createWindow() throws Exception {
		Display.setFullscreen(fullscreen);
		DisplayMode d[] = Display.getAvailableDisplayModes();
		for (int i = 0; i < d.length; i++) {
			if (d[i].getWidth() == 1024 && d[i].getHeight() == 768
					&& d[i].getBitsPerPixel() == 32) {
				displayMode = d[i];
				break;
			}
		}
		Display.setDisplayMode(displayMode);
		//Display.setTitle(windowTitle);
		Display.create();
	}

	private void init() throws Exception {
		createWindow();

		initGL();
	}


	private void initGL() {
		GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping
		GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
		GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
		GL11.glClearDepth(1.0); // Depth Buffer Setup
		GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
		GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do

		GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
		GL11.glLoadIdentity(); // Reset The Projection Matrix

		// Calculate The Aspect Ratio Of The Window
		GLU.gluPerspective(45.0f, (float) displayMode.getWidth()
				/ (float) displayMode.getHeight(), 0.1f, 100.0f);
		GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix

		// Really Nice Perspective Calculations
		GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
	}

	private static void cleanup() {
		Display.destroy();
	}
}